﻿using Microsoft.Extensions.Configuration;

namespace Luka;

/// <summary>
/// 基础配置文件
/// </summary>
[NotScanned]
internal static class BaseConfiguration
{
    /// <summary>
    /// 自动合并配置文件
    /// </summary>
    public static void MergeConfiguration(this IConfigurationBuilder configuration)
    {
        // 获取程序执行目录
        var executeDirectory = AppDomain.CurrentDomain.BaseDirectory;
        // 设置基本路径
        configuration.SetBasePath(executeDirectory);
        // 配置项
        configuration.AddJsonFile("appsettings.json", true, true);
        // 用户自定义环境配置
        configuration.AddJsonFile($"appsettings.{InternalApp.EnvironmentName}.json", true, true);
        // 获取根配置
        var config = configuration.Build();
        // 自定义配置文件目录名称
        var dirs = config.GetSection("ConfigurationDirectory").Get<string[]>() ?? Array.Empty<string>();


        // 获取自定义配置目录下的 json 文件
        var jsonFiles = new[] { executeDirectory }
                            .Concat(dirs.Where(dir => Directory.Exists(dir)))
                            .SelectMany(u => Directory.GetFiles(u, "*.json", SearchOption.TopDirectoryOnly));
        // 没有配置文件，中止执行
        if (!jsonFiles.Any()) return;
        // 忽略的配置文件
        var ignoreFiles = config.GetSection("IgnoreConfigurationFiles").Get<string[]>() ?? Array.Empty<string>();
        var filesGroups = SplitConfigFileNameToGroups(jsonFiles.Where(it => !ignoreFiles.Contains(it.Split('.')[0])));
        foreach (var group in filesGroups)
        {
            // 限制查找的 json 文件组
            var limitFileNames = new[] { $"{group.Key}.json", $"{group.Key}.{InternalApp.EnvironmentName}.json" };
            // 查找默认配置和环境配置
            var files = group
                .Where(u => limitFileNames.Contains(Path.GetFileName(u), StringComparer.OrdinalIgnoreCase))
                .OrderBy(u => Path.GetFileName(u).Length);

            // 循环加载
            foreach (var jsonFile in files)
            {
                configuration.AddJsonFile(jsonFile, optional: true, reloadOnChange: true);
            }
        }
    }

    /// <summary>
    /// 对配置文件名进行分组
    /// </summary>
    /// <param name="configFiles"></param>
    /// <returns></returns>
    private static IEnumerable<IGrouping<string, string>> SplitConfigFileNameToGroups(IEnumerable<string> configFiles)
    {
        // 分组
        return configFiles.GroupBy(Function);
        // 本地函数
        static string Function(string file)
        {
            // 根据 . 分隔
            var fileNameParts = Path.GetFileName(file).Split('.', StringSplitOptions.RemoveEmptyEntries);
            if (fileNameParts.Length == 2) return fileNameParts[0];

            return string.Join('.', fileNameParts.Take(fileNameParts.Length - 2));
        }
    }
}